package com.sq.util.web.initer;

import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sq.util.BeanUtil;
import com.sq.util.ClassUtil;
import com.sq.util.exception.CommonException;
import com.sq.util.exception.VisualException;
import com.sq.util.web.XssUtil;
import com.sq.util.web.validation.ParamName;
import com.sq.util.web.validation.ValidInt;
import com.sq.util.web.validation.ValidLong;
import com.sq.util.web.validation.ValidNotEmpty;
import com.sq.util.web.validation.ValidNotNull;
import com.sq.util.web.validation.ValidRegex;
import com.sq.util.web.validation.ValidStringLength;

public class JsonIniter extends BaseIniter {

    private static Logger log = LoggerFactory.getLogger(JsonIniter.class);

    @SuppressWarnings("rawtypes")
    public static <T> List<T> initList(List<Map> data, Class<T> cls) {
        List<T> result = new LinkedList<T>();
        for (Map map : data) {
            result.add(initInstance(map, cls));
        }
        return result;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static <T> T initInstance(Map map, Class<T> cls) {
        Object obj = null;
        try {
            obj = cls.newInstance();
        } catch (Exception e) {
            throw new CommonException("不能实例化" + cls.getName());
        }
        List<Field> list = BeanUtil.getFields(cls);
        for (Field field : list) {
            if (field == null) {
                continue;
            }
            if (field.isAnnotationPresent(InitIgnore.class)) {
                continue;
            }
            String name = field.getName();
            if (field.isAnnotationPresent(ParamName.class)) {
                ParamName paramName = field.getAnnotation(ParamName.class);
                initProperty(cls, obj, field, map.get(paramName.name()));
            } else {
                initProperty(cls, obj, field, map.get(name));
            }
        }
        return (T) obj;
    }

    private static void initProperty(Class<?> cls, Object Obj, Field field, Object valueStr) {
        try {
            _initProperty(cls, Obj, field, valueStr);
        } catch (VisualException e) {
            log.error("处理类[{}]的属性[{}]出错:{}", cls.getName(), field.getName(), e.getMessage());
            throw e;
        } catch (RuntimeException e) {
            log.error("处理类[" + cls.getName() + "]的属性[" + field.getName() + "]出错:", e);
            throw e;
        }
    }

    private static void _initProperty(Class<?> cls, Object Obj, Field field, Object value) {
        if (field.isAnnotationPresent(ValidNotNull.class)) {
            checkNotNull(field, value);
        } else if (field.isAnnotationPresent(ValidRegex.class)) {
            value = checkRegex(field, (String) value);
        } else if (field.isAnnotationPresent(ValidInt.class)) {
            value = checkInt(field, (Integer) value);
        } else if (field.isAnnotationPresent(ValidLong.class)) {
            value = checkLong(field, (Long) value);
        } else if (field.isAnnotationPresent(ValidNotEmpty.class)) {
            checkStringNotEmpty(field, (String) value);
        } else if (field.isAnnotationPresent(ValidStringLength.class)) {
            checkStringLength(field, (String) value);
        } else if (field.isAnnotationPresent(LimitLower.class)) {
            value = checkLimitLower(field, value);
        }
        if (value == null) {
            return;
        }
        if (ClassUtil.isString(field.getType())) {
            XssUtil.checkXSS(value.toString());
        }
        setProperty(cls, Obj, field, value);
    }

}
